﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Globalization;
using System.ComponentModel;

namespace DSPL.Common.CommonControls.Controls
{
   
    public class TxtNumber :TextBox
    {
        private string _maskText=string.Empty;
        static TxtNumber()
        {
            //override the meta data for the Text Proeprty of the textbox 
            FrameworkPropertyMetadata metaData = new FrameworkPropertyMetadata();
            metaData.CoerceValueCallback = ConvertToFormat;
           TextProperty.OverrideMetadata(typeof(TxtNumber), metaData);
         //  DependencyProperty.RegisterAttached("NumberFormat", typeof(string), typeof(TxtNumber));


        }
        #region Dependency Properties
        public static readonly DependencyProperty MasterUnityContainerProperty = DependencyProperty.Register("MasterUnityContainer", typeof(object), typeof(TxtNumber), new PropertyMetadata());
        #endregion

        #region Properties
        public object MasterUnityContainer
        {
            get
            {
                return ((object)GetValue(MasterUnityContainerProperty));
            }
            set
            {
                SetValue(MasterUnityContainerProperty, value);

            }
        }
        #endregion

        public string NumberFormat
        {
            get { return (string)GetValue(NumberFormatProperty); }
            set
            {
                this.SetValue(NumberFormatProperty, value);
           
            }
        }
        public static readonly DependencyProperty NumberFormatProperty = DependencyProperty.Register(
         "NumberFormat", typeof(string), typeof(TxtNumber), new PropertyMetadata(string.Empty));

        
        public MaskedTextProvider MaskProvider
        {
            get
            {
                MaskedTextProvider maskProvider = null;
                if (NumberFormat != null)
                {
                    maskProvider = new MaskedTextProvider(NumberFormat);
                    maskProvider.Set(Text);
                    maskProvider.ResetOnSpace = true;
                    maskProvider.IncludePrompt = false;
                }
                return maskProvider;
            }           
        }


        protected override void OnGotFocus(RoutedEventArgs e)
        {
            this.SelectionStart = 0;
            this.SelectionLength = this.Text.Length;
            this.Select(0, this.Text.Length);
        }


        protected override void OnMouseDoubleClick(MouseButtonEventArgs e)
        {
            base.OnMouseDoubleClick(e);
            this.Select(0, this.Text.Length);
        }
        
        protected override void OnLostFocus(RoutedEventArgs e)
        {
            MaskedTextProvider provider = MaskProvider;           
            string value = Text;
           
            string previousValue = value;
            value = value.Replace("_", "");
            if (value != "0")
            {
                if (NumberFormat.IndexOf(".") > 0)
                {
                    int numberFormatLength = NumberFormat.Length;
                    int decimalPosition = NumberFormat.IndexOf(".");
                    int currentDecimalPosition = value.IndexOf(".");
                    int currentNumberLength = value.Length;
                    value = value.Substring(0, currentDecimalPosition) + "." + value.Substring(currentDecimalPosition + 1, currentNumberLength - (currentDecimalPosition + 1)).PadRight(numberFormatLength - decimalPosition - 1, '0');
                    //value = value.Substring(0, currentDecimalPosition).PadLeft(decimalPosition, '0') + "." + value.Substring(currentDecimalPosition + 1, currentNumberLength - (currentDecimalPosition + 1)).PadRight(numberFormatLength - decimalPosition - 1, '0');
                }
                else
                {
                    value = value.PadLeft(NumberFormat.Length, '0');
                }
            }
            provider.Set(value);
            provider.ResetOnPrompt = true;
            Text = value;
            base.OnLostFocus(e);
        }

        protected override void OnPreviewTextInput(TextCompositionEventArgs e)
        {

            base.OnPreviewTextInput(e);

            int position = SelectionStart;
            int decimalPointIndex = this.Text.IndexOf('.');

            if (e.Text == ".")
            {
                
                position = this.Text.IndexOf('.');
                if (position == -1)
                    position = SelectionStart;
            }
            MaskedTextProvider provider = MaskProvider;

            if (position <= Text.Length)
            {
                position = GetNextCharacterPosition(position);

                if (Keyboard.IsKeyToggled(Key.Insert))
                {
                    if (provider.Replace(e.Text, position))
                        position++;
                }
               
                else
                {
                    if (provider.InsertAt(e.Text, position))
                        position++;
                }

                position = GetNextCharacterPosition(position);
            }

            RefreshText(provider, position);
            e.Handled = true;
        }

        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            base.OnPreviewKeyDown(e);
            MaskedTextProvider provider = MaskProvider;
            provider.ResetOnSpace = true;
            provider.IncludePrompt = false;
            provider.SkipLiterals = true;
            int position = SelectionStart;
            int endLength = SelectionLength;

            if (endLength == 0)
                endLength = 1;


            if (e.Key == Key.Delete && position < Text.Length)
            {
                string fieldValue = this.Text;

                if (endLength == 1)
                {
                  //  position--;
                    provider.RemoveAt(position);
                }
                else
                {
                    provider.RemoveAt(position, position + endLength - 1);
                }

                if (position == 0)
                {
                    RefreshText(provider, position + endLength);
                }
                else
                {
                    RefreshText(provider, position);
                }
                if (endLength == 1)
                {
                    this.SelectionStart = position;
                }
                else
                {
                     this.SelectionStart = 0;
                }
                e.Handled = true;
            }
         
            else if (e.Key == Key.Space)
            {
                
                e.Handled = true;
            }

            else if (e.Key == Key.Back)
            {
                if (position > 0)
                {
                    position--;
                    provider.RemoveAt(position);
                    RefreshText(provider, position);

                    e.Handled = true;
                }
            }

            else
            {
                string fieldValue = this.Text;

                if (e.Key >= Key.D0 && e.Key <= Key.D9)
                {
                    if (endLength >= 1)
                    {
                        if (endLength == 1)
                        {
                            // position--;
                            provider.RemoveAt(position);
                        }
                        else
                        {
                            provider.RemoveAt(position, position + endLength-1);
                        }

                        if (position == 0)
                        {
                            RefreshText(provider, position + endLength-1);
                        }
                        else
                        {
                            RefreshText(provider, position);
                        }
                        if (endLength != 1)
                            this.SelectionStart = 0;
                        //e.Handled = true;
                    }
                }
            }
           
        }

        public void RefreshText(MaskedTextProvider provider, int position)
        {
            Text =(provider.ToDisplayString());
          // Text = (provider.ToString());
            SelectionStart = position;
        }
        //gets the next position in the textbox to move
        private int GetNextCharacterPosition(int startPosition)
        {
            int position = MaskProvider.FindEditPositionFrom(startPosition, true);
            if (position == -1)
                return startPosition;
            else
                return position;
        }
        private static object ConvertToFormat(DependencyObject sender, object value)
        {
            TxtNumber textBox = (TxtNumber)sender;
            if (textBox.NumberFormat != null)
            {
                string previousFormat = textBox.NumberFormat;
                string previousValue = value.ToString();
                previousValue = previousValue.ToString().Replace("_", "");
                previousValue = previousValue.ToString().Replace(".", "");

                if ((value != null) && (previousValue != string.Empty))
                {
                    textBox.NumberFormat = value.ToString();
                }
                if (textBox.NumberFormat != string.Empty)
                {
                    MaskedTextProvider provider = new MaskedTextProvider(textBox.NumberFormat);

                    provider.Set((string)value);
                    textBox.NumberFormat = previousFormat;
                    return provider.ToString();
                }
                else
                {
                    return "";
                }
              //return provider.ToDisplayString();
            }
            else
            {
                return value;
            }
        }

        protected virtual void ResolveDependencies()
           {
           }
    }
}
